package com.itqf.advice;

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.springframework.aop.AfterReturningAdvice;
import org.springframework.aop.MethodBeforeAdvice;
import org.springframework.aop.ThrowsAdvice;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;

/**
 * projectName: springframeworkgp8
 *
 * @author: 赵伟风
 * time: 2021/8/4 14:44
 * description:标准化增强
 */
@Component("advice")
public class StandardAdvice implements MethodBeforeAdvice, AfterReturningAdvice, ThrowsAdvice, MethodInterceptor {
    /**
     * Callback before a given method is invoked.
     *
     * @param method the method being invoked
     * @param args   the arguments to the method
     * @param target the target of the method invocation. May be {@code null}.
     * @throws Throwable if this object wishes to abort the call.
     *                   Any exception thrown will be returned to the caller if it's
     *                   allowed by the method signature. Otherwise the exception
     *                   will be wrapped as a runtime exception.
     */
    @Override
    public void before(Method method, Object[] args, Object target) throws Throwable {
        String name = method.getName();
        System.out.println("name = " + name);
        String simpleName = target.getClass().getSimpleName();
        System.out.println("simpleName = " + simpleName);
        System.out.println("StandardAdvice.before");
    }

    /**
     * Callback after a given method successfully returned.
     *
     * @param returnValue the value returned by the method, if any
     * @param method      the method being invoked
     * @param args        the arguments to the method
     * @param target      the target of the method invocation. May be {@code null}.
     * @throws Throwable if this object wishes to abort the call.
     *                   Any exception thrown will be returned to the caller if it's
     *                   allowed by the method signature. Otherwise the exception
     *                   will be wrapped as a runtime exception.
     */
    @Override
    public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {
        System.out.println("StandardAdvice.afterReturning");
    }


    public void afterThrowing(Method method, Object[] args, Object target, Exception ex){
        System.out.println("StandardAdvice.afterThrowing");
        System.out.println(ex.getMessage());
    }


    @Override
    public Object invoke(MethodInvocation invocation) throws Throwable {

        System.out.println("StandardAdvice.invoke");
        System.out.println("StandardAdvice.invoke");

        Object proceed = invocation.proceed();

        return proceed;
    }
}
